package controllers.admin

import controllers.{RequestAsJson, checkAdmin}
import models.users._

import javax.inject.Inject
import play.api.Logging
import play.api.data.Form
import play.api.data.Forms._
import play.api.libs.functional.syntax._
import play.api.libs.json.Reads._
import play.api.libs.json._
import play.api.mvc._
import services.freenas.FreeNASManage

import scala.concurrent.{ExecutionContext, Future}

class NasController @Inject()(nasRepo: AppNasUsersRepository, nas: FreeNASManage,
                              cc: ControllerComponents
                             )(implicit
                               exec: ExecutionContext, parser: BodyParsers.Default)
  extends AbstractController(cc) with play.api.i18n.I18nSupport with RequestAsJson with Logging {

  val userForm: Form[NasUserInfo] = Form {
    mapping(
      "p1" -> nonEmptyText,
      "p2" -> nonEmptyText,
      "p3" -> default(text(minLength = 5, maxLength = 16), "Wy111111111111")
    )(NasUserInfo.apply)(NasUserInfo.unapply)
  }

  def index() = checkAdmin(parser, exec) { implicit request =>
    Ok(views.html.nas.check("nas index"))
  }

  def users() = checkAdmin.async { implicit request =>
    nasRepo.nasGroupAll.map(group =>
      Ok(views.html.nas.users("nas user", group))
    )
  }



  def userList() = checkAdmin(parse.json, exec).async { implicit request =>
    val placeResult = request.body.validate[ListParameters]
    logger.debug(placeResult.toString)
    placeResult.fold(
      errors => {
        Future(BadRequest(Json.obj("code" -> 0, "message" -> JsError.toJson(errors), "count" -> 0, "data" -> errors.toString())))
      },
      p => {
        logger.debug(p.toString)
        val res = nasRepo.nasUserList(p.page-1, p.limit, p.query, layui_switch(p.active))
        implicit val tableResJson = Json.format[NasUserLayuiTable]
        res.flatMap {
          page =>
            nasRepo.nasGroupAll.map {
              groups => {
                val data = page._1.map(
                  i => {
                    val group = groups.filter(f => f.id == i._5)
                    NasUserLayuiTable(
                      i._1,
                      i._2,
                      if (i._3 == 0) "否" else "是" ,
                      i._4.getOrElse(""),
                      if (group.nonEmpty) group.head.pname else "",
                      if (i._6.getOrElse(false)) "是" else "否",
                      if (i._7.getOrElse(false)) "是" else "否",
                    )
                  }
                )
                Ok(Json.obj("code" -> 0, "message" -> "", "count" -> page._2, "data" -> Json.toJson(data)))
              }
            }
        }
      }
    )

  }

  def userCreate() = checkAdmin(parser, exec) { implicit request =>
    Ok("nas create user")
  }

  def userLocked() = checkAdmin(parser, exec) { implicit request =>
    Ok(s"nas locked user(未完成)\n ${request.body.toString} ")
  }

  def userChangeGroup() = checkAdmin(parser, exec) { implicit request =>
    request.contentType.getOrElse("") match {
      case "application/json" => {
        //        logger.debug("userChangeGroup is application/json")
        val bd = request.body.asJson.getOrElse(Json.arr(List(Json.obj("id" -> 0, "gid" -> 0))))
        logger.debug(bd.toString)
        try {
          val iter = bd.as[JsArray].value.iterator
          while (iter.hasNext) {
            val i = iter.next()
            val id = i("id").as[Int]
            val gid = i("gid").as[String].toInt
            nas.userGroupUpdate(id, gid).map(res => logger.debug(s"userChangeGroup ${i.toString} is $res"))
          }
        } catch {
          case e: Exception => logger.error("userChangeGroup error: ", e)
        }
        Ok("userChangeGroup")
      }
      case _ => Redirect(controllers.admin.routes.NasController.users()).flashing("success" -> "nas  false!")
    }
  }

  def groups() = checkAdmin(parser, exec) { implicit request =>
    Ok(views.html.nas.groups("nas group"))
  }

  def groupList() = checkAdmin(parse.json, exec).async { implicit request =>
    val placeResult = request.body.validate[ListParameters]
    logger.debug(placeResult.toString)
    placeResult.fold(
      errors => {
        Future(BadRequest(Json.obj("code" -> 0, "message" -> JsError.toJson(errors), "count" -> 0, "data" -> Json.arr())))
      },
      p => {
        logger.debug(s"Nas groups list form = ${p.toString()}")
        val res = nasRepo.nasGroupList(p.page-1, p.limit, p.query)
        implicit val tableResJson = Json.format[NasGroupLayuiTable]
        res.map {
          page => {
            val data = page._1.map(
              i =>
                NasGroupLayuiTable(i.id, if (i.nas_id == 0) None else Some(i.nas_id), i.nas_name, i.pname)
            )
            Ok(Json.obj("code" -> 0, "message" -> "", "count" -> page._2, "data" -> Json.toJson(data)))
          }
        }
      }
    )
  }

  def groupCreate() = checkAdmin(parser, exec) { implicit request =>
    Ok(views.html.nas.groupcreate("nas group"))
  }

  def groupUpdate() = checkAdmin.async { implicit request =>
    userForm.bindFromRequest().fold(
      //      errorForm => Future.successful(Ok(views.html.nas.profile(Array("nas_profile","readonly"),errorForm))),
      errorForm => Future.successful(Redirect(controllers.admin.routes.NasController.groups()).flashing("success" -> "nas group create false!")),
      p => {
        logger.debug(p.toString)

        nas.groupCreate(p.p2).map { r =>
          if (r != 0) {
            Redirect(controllers.admin.routes.NasController.groups())
              .flashing("success" -> "nas group create Ok!")
          }
          else Redirect(controllers.admin.routes.NasController.groups()).flashing("success" -> "nas group create false!")
        }
      }
    )
  }

  def nasGroupsCheck() = checkAdmin(parser, exec).async { implicit request =>
    nas.groupCheck.map(r => Ok(r.toString))
  }

  def nasUsersCheck() = checkAdmin(parser, exec).async { implicit request =>
    nas.userCheck.map(r => Ok(r.toString))
  }

  def setGroupAsNasGroupId() = checkAdmin(parser, exec) { implicit request =>
    request.contentType.getOrElse("") match {
      case "application/json" => {
        //        logger.debug("userChangeGroup is application/json")
        val bd = request.body.asJson.getOrElse(Json.arr(List(Json.obj("id" -> 0, "gid" -> 0))))
        logger.debug(bd.toString)
        try {
          val iter = bd.as[JsArray].value.iterator
          while (iter.hasNext) {
            val i = iter.next()
            val id = i("id").as[Int]
            val gid = i("gid").as[String].toInt
            nas.setGroupId(id, gid).map(res => logger.debug(s"setGroupId ${i.toString} is $res"))
          }
        } catch {
          case e: Exception => logger.error("setGroupId error: ", e)
        }
        Ok("setGroupId")
      }
      case _ => Redirect(controllers.admin.routes.NasController.users()).flashing("success" -> "nas  false!")
    }
  }
}




case class NasUserLayuiTable(
                              id: Option[Int] = None,
                              username: String = "",
                              actived: String = "false",
                              nas_name: String = "",
                              group_name: String = "",
                              locked: String = "",
                              checked:String=""
                            )

case class NasGroupLayuiTable(
                               id: Option[Int] = None,
                               group_id: Option[Int] = None,
                               nas_name: String = "",
                               pname: String = "",
                             )

